package com.roadmap.biz.common;

import java.lang.reflect.Constructor;

import org.apache.log4j.Logger;

import com.roadmap.common.RdcConst;
import com.roadmap.common.RdcLogger;
import com.roadmap.exception.InvalidValueException;
import com.roadmap.exception.NullObjectException;
import com.roadmap.exception.ServerException;

/** 通过此类管理manager实例 */
public final class ManagerFactory {
	private final static Logger _log = RdcLogger
			.getLogger(ManagerFactory.class);

	/** 此类不能创建实例 */
	private ManagerFactory() {
	}

	/**
	 * 根据类型获得一个manager实例
	 * 
	 * @param: type - manager 类型
	 * @param: currentUser - 当前用户
	 * @param： values: itemOwner - 访问项的所有者; parentClazz - 如果type=访问项的父项
	 */
	public static IManager getInstance(String type, String currentUser,
			String... values) throws InvalidValueException, ServerException {
		if (currentUser == null || currentUser == null) {
			NullObjectException e = new NullObjectException();
			_log.error("users should be not NULL.", e);
			throw e;
		}

		String managerClazzName = RdcConst.getManagerNameClazz(type);
		if (managerClazzName == null) {
			InvalidValueException e = new InvalidValueException();
			_log.error(type + " is not mapped to a manager class.", e);
			throw e;
		}

		// 默认当前用户是item的owner
		String itemOwner = currentUser;
		Class clazz = null;
		if (values != null && values.length >= 1) {
			itemOwner = values[0];

			if (values.length > 1) {
				// 得到实体的父类型
				clazz = RdcConst.getEntityNameClazz(values[1]);
			}
		}

		if (clazz == null && RdcConst.getCommonEntityNameSet().contains(type)) {
			// 得到实体类型
			clazz = RdcConst.getEntityNameClazz(type);
		}

		return getInstance(managerClazzName, currentUser, itemOwner, clazz);
	}

	private static IManager getInstance(String managerClazzName,
			String currentUser, String itemOwner, Class clazz)
			throws ServerException {
		try {
			Class managerClazz = Class.forName(managerClazzName);
			if (clazz == null) {
				Constructor ctr = managerClazz.getDeclaredConstructor(
						String.class, String.class);
				return (IManager) ctr.newInstance(currentUser, itemOwner);
			}
			else {
				Constructor ctr = managerClazz.getDeclaredConstructor(
						String.class, String.class, clazz.getClass());
				return (IManager) ctr
						.newInstance(currentUser, itemOwner, clazz);
			}
		}
		catch (Exception e) {
			ServerException e1 = new ServerException();
			_log.error("Failed to create a new instance for "
					+ managerClazzName, e);
			throw e1;
		}
	}
}
